package com.beta.restapi.controller;

import com.baomidou.mybatisplus.plugins.Page;
import com.beta.common.web.ContentType;
import com.beta.dto.cart.CartSettleDto;
import com.beta.dto.order.CreateOrderDto;
import com.beta.dto.order.OrderStatusCountDto;
import com.beta.dto.order.OrdersDto;
import com.beta.em.order.OrderMode;
import com.beta.em.order.OrderStatus;
import com.beta.em.order.PayMode;
import com.beta.em.order.PayStatus;
import com.beta.restapi.internal.Consts;
import com.beta.restapi.request.order.CreateOrderRequest;
import com.beta.service.*;
import com.beta.vo.cart.CartSettleVO;
import com.beta.vo.order.CreateOrderVO;
import com.beta.vo.order.OrderCanPayVO;
import com.beta.vo.order.OrderPageVO;
import com.beta.vo.order.OrderVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Created by vector on 2016/11/24.
 */
@Api(tags = "Order")
@RestController
@RequestMapping(Consts.API_PATH_PREFIX + Consts.Resource.ORDERS)
public class OrderController extends BaseController {

    @Autowired
    private MapperFacade beanMapper;
    @Autowired
    private IOrderOperateService orderOperateService;
    @Autowired
    private IOrdersService ordersService;
    @Autowired
    private ICartItemsService cartItemsService;
    @Autowired
    private IOrderItemsService orderItemsService;
    @Autowired
    private IReceiversService receiversService;

    @ApiResponses({@ApiResponse(code = 200, message = "success", response = CartSettleVO.class)})
    @GetMapping(value = "/new")
    public Object cartSettlement(@RequestHeader(Consts.HEADER_AUTH_KEY) String token,
                                 @RequestParam("cart_item_ids[]") List<Integer> cartItemsIds) {
        CartSettleDto cartSettleDto = cartItemsService.settleCartItems(cartItemsIds);
        return ok(beanMapper.map(cartSettleDto, CartSettleVO.class));
//        List<CartSettleItemsDto> productOrdersDtoList = orderItemsService.cartSettlement(cartItemsIds);
//        List<Receivers> receiversList = receiversService.getReceiversByUserId(getCurrentUserId());
//        ProductOrdersVO productOrdersVO = new ProductOrdersVO();
//        productOrdersVO.setPayMode(PayMode.ONLINE.getValue());
//        productOrdersVO.setMode(OrderMode.BUYING.getValue());
//        productOrdersVO.setReceivers(receiversList);
//        productOrdersVO.setOrderItems(productOrdersDtoList);
//        BigDecimal sumUnitWeight = BigDecimal.ZERO;
//        BigDecimal sumFreight = BigDecimal.ZERO;
//        BigDecimal sumPrice = BigDecimal.ZERO;
//        int sumQuantity = 0;
//        BigDecimal unitFreight = BigDecimal.ZERO;
//        BigDecimal unitWeight = BigDecimal.ZERO;
//        BigDecimal amount = BigDecimal.ZERO;
//        for (CartSettleItemsDto productOrderDto : productOrdersDtoList) {
//            //单个商品重量
//            unitWeight = productOrderDto.getUnitWeight().multiply(new BigDecimal(productOrderDto.getQuantity()));
//            //重量配送费=每公斤配送费*单款商品
//            BigDecimal freight = productOrderDto.getUnitFreight();
//            BigDecimal productTotalFeightPrice = freight.multiply(unitWeight);
//            //单个商品总价=（商品单价*数量）+（运费）
//            Integer quantity = productOrderDto.getQuantity();
//            BigDecimal price = productOrderDto.getPricePerUnit();
//            BigDecimal productPrice = price.multiply(new BigDecimal(quantity));
//            BigDecimal productTotalPrice = productPrice.add(productTotalFeightPrice);
//            //单个商品价格
//            productOrderDto.setPrice(productPrice);
//            //总运费（单个商品运费累加）
//            sumFreight = productTotalFeightPrice.add(sumFreight);
//            //总重量
//            sumUnitWeight = unitWeight.add(sumUnitWeight);
//            //总数量
//            sumQuantity = sumQuantity + productOrderDto.getQuantity();
//
//            //商品总价
//            sumPrice = productPrice.add(sumPrice);
//
//            //订单总支出（商品价格+ 运费）
//            amount = productTotalPrice.add(amount);
//            //运费单价( 货物配送站的每公斤运费)
//            unitFreight = productOrderDto.getUnitFreight();
//        }
//        productOrdersVO.setFreight(sumFreight);
//        productOrdersVO.setWeight(sumUnitWeight);
//        productOrdersVO.setQuantity(sumQuantity);
//        productOrdersVO.setPrice(sumPrice);
//        productOrdersVO.setAmount(amount);
//        productOrdersVO.setCartItems(cartItemsIds);
//        productOrdersVO.setUnitFreight(unitFreight);
//        return ok(productOrdersVO);
    }

    @ApiResponses(@ApiResponse(code = 200, message = "success", response = CreateOrderVO.class))
    @PostMapping(value = "", produces = {ContentType.JSON}, consumes = {ContentType.JSON})
    public Object createOrder(@RequestHeader(Consts.HEADER_AUTH_KEY) String token,
                              @RequestBody CreateOrderRequest requestBody) {
        CreateOrderDto createOrderDto = new CreateOrderDto();
        createOrderDto.setReceiverId(requestBody.getReceiverId());
        createOrderDto.setPayMode(PayMode.getPayMode(requestBody.getPayMode()));
        createOrderDto.setOrderMode(OrderMode.getOrderMode(requestBody.getMode()));
        createOrderDto.setCartItemIds(requestBody.getCartItemIds());
        OrdersDto ordersDto = orderOperateService.createOrder(getCurrentUserId(), createOrderDto);
        CreateOrderVO createOrderVo = new CreateOrderVO();
        createOrderVo.setPayment(ordersDto.getPayable());
        createOrderVo.setOrderId(ordersDto.getId());
        return ok(createOrderVo);
    }

    @ApiResponses(@ApiResponse(code = 200, message = "success", response = OrderPageVO.class))
    @GetMapping(value = "", produces = {ContentType.JSON})
    public Object getOrders(@RequestHeader(Consts.HEADER_AUTH_KEY) String token) {
        Page<OrdersDto> orders = ordersService.getOrders(getCurrentUserId(), getMybatisPage());
        return ok(toOrderPageVO(orders));
    }

    @ApiResponses(@ApiResponse(code = 200, message = "success", response = OrderPageVO.class))
    @GetMapping(value = "/unpaid", produces = {ContentType.JSON})
    public Object getUnpaidOrders(@RequestHeader(Consts.HEADER_AUTH_KEY) String token) {
        Page<OrdersDto> unpaidOrders = ordersService.getUnpaidOrders(getCurrentUserId(), getMybatisPage());
        return ok(toOrderPageVO(unpaidOrders));
    }

    @ApiResponses(@ApiResponse(code = 200, message = "success", response = OrderPageVO.class))
    @GetMapping(value = "/delivering", produces = {ContentType.JSON})
    public Object getDeliveringOrders(@RequestHeader(Consts.HEADER_AUTH_KEY) String token) {
        Page<OrdersDto> deliveringOrders = ordersService.getDeliveringOrders(getCurrentUserId(), getMybatisPage());
        return ok(toOrderPageVO(deliveringOrders));
    }

    @ApiResponses(@ApiResponse(code = 200, message = "success", response = OrderPageVO.class))
    @GetMapping(value = "/complete", produces = {ContentType.JSON})
    public Object getCompleteOrders(@RequestHeader(Consts.HEADER_AUTH_KEY) String token) {
        Page<OrdersDto> completeOrders = ordersService.getCompleteOrders(getCurrentUserId(), getMybatisPage());
        return ok(toOrderPageVO(completeOrders));
    }

    private Object toOrderPageVO(Page<OrdersDto> ordersDtoPage) {
        List<OrdersDto> dtoRows = ordersDtoPage.getRecords();
        OrderPageVO orderPageVO = new OrderPageVO();
        orderPageVO.setOrders(beanMapper.mapAsList(dtoRows, OrderVO.class));
        fillPageParam(ordersDtoPage, orderPageVO);
        return orderPageVO;
    }

    @GetMapping(value = "/{orderId}", produces = {ContentType.JSON})
    public Object getOrder(@RequestHeader(Consts.HEADER_AUTH_KEY) String token,
                           @PathVariable("orderId") Integer orderId) {
        OrdersDto order = ordersService.getOrder(orderId);
        return ok(beanMapper.map(order, OrderVO.class));
    }

    @PatchMapping(value = "/{orderId}/cancel", produces = {ContentType.JSON})
    public Object cancelOrder(@RequestHeader(Consts.HEADER_AUTH_KEY) String token,
                              @PathVariable("orderId") Integer orderId) {
        orderOperateService.executeCancelOrder(orderId);
        return ok();
    }

    @GetMapping(value = "{orderId}/canpay")
    public Object canPay(@RequestHeader(Consts.HEADER_AUTH_KEY) String token,
                         @PathVariable("orderId") Integer orderId) {
        Boolean canPay = ordersService.canPay(orderId);
        OrderCanPayVO canPayVO = new OrderCanPayVO();
        canPayVO.setCanpay(canPay);
        return ok(canPayVO);
    }

    @GetMapping(value = "/status", produces = {ContentType.JSON})
    public Object getOrderStatusCount(@RequestHeader(Consts.HEADER_AUTH_KEY) String token) {
        Map<String, Integer> map = new HashMap<>();
        OrderStatusCountDto ordersStatusCount = ordersService.getOrdersStatusCount(getCurrentUserId());
        map.put(PayStatus.UNPAID.getValue(), ordersStatusCount.getUnpaid());
        map.put(OrderStatus.DELIVERING.getValue(), ordersStatusCount.getDelivering());
        return ok(map);
    }

    @PatchMapping(value = "/{orderId}/confirm", produces = {ContentType.JSON})
    public Object confirmOrder(@RequestHeader(Consts.HEADER_AUTH_KEY) String token, @PathVariable("orderId") Integer orderId) {
        orderOperateService.executeReceiptConfirm(orderId);
        return ok();
    }

}
